/******************************************************************************
** 
** File name:	UTEST_12.c
**	
** Description: RTOS Unit Tests. Basic ISR Management Tests. 
**				- Two interrupt sources of the same level.
**				- NESTED interrupts.
**
** Tested APIs:	RTOS_TaskResumeISR()
**
** Notes:		Requires HW to execute!
**
******************************************************************************/
#include <avr/io.h>
#include <avr/interrupt.h>
#include "rtos.h"
#include "utest.h"

/******************************************************************************
**	RTOS DECLARARTION SECTION
**
**  Standard config for RTOS MESSAGE QUEUE Services Unit Tests should look
**	as follows:
**
**	Timer interrupt #1:			USER_TimerHandler_1 (defined by USER), 
**								HIGH Priority.
**	Timer interrupt #2:			USER_TimerHandler_2 (defined by USER),
**								LOW Priority.
**
**	Events:						n/a
**	Messages:					n/a
**	Queues:						n/a
**	Timers:						n/a
**	
**	Three tasks:				tsk1,		tsk2,		tsk3 
**  Three priorities:			1 (high)	2 (middle)	3 (low)
**  Stack size:					20			20			20
**
**  Notes:	
**
******************************************************************************/

RTOS_DECLARE_ISR(USER_TIMER_1_VECTOR,USER_TimerHandler_1);
RTOS_DECLARE_ISR(USER_TIMER_2_VECTOR,USER_TimerHandler_2);

RTOS_DECLARE_TASK(tsk1, 20, 1);
RTOS_DECLARE_TASK(tsk2, 20, 2);
RTOS_DECLARE_TASK(tsk3, 20, 3);

UTST_TIMER_t	usr_tmr_1 =
{
	&(USER_TIMER_1),
	20000,
	LEVEL_HIGH,
	STATE_STOP
};

UTST_TIMER_t	usr_tmr_2 =
{
	&(USER_TIMER_2),
	20001,
	LEVEL_LOW,
	STATE_STOP
};

/******************************************************************************
	UNIT TEST MAIN FUNCTION
******************************************************************************/
int main(void)
{
	UTST_INIT_HW();

	utst_init_timer(&usr_tmr_1);
	utst_init_timer(&usr_tmr_2);
	
    RTOS_TaskStartExp(tsk1);
    RTOS_TaskStartExp(tsk2);
    RTOS_TaskStartExp(tsk3);

	UTST_TIMER_START(USER_TIMER_2);
	UTST_TIMER_START(USER_TIMER_1);

	RTOS_DebugLog("RTOS::StartOS()");

    RTOS_Initialize(0);
	RTOS_StartOS();
	
    while(1);	
}

/******************************************************************************
	UNIT TEST INTERRUPT FUNCTION[s]
******************************************************************************/
/*
** User' Timer Handler #1
*/
RTOS_ISR_FUNC(USER_TimerHandler_1)
{
	RTOS_DebugLog("TIMER_ISR_#1::ENTER");
	RTOS_DebugOutDump();
	
	RTOS_DebugLog("TIMER_ISR_#1::Resume Task#2");
	RTOS_TaskResumeISR(&tsk2PID);
	
	RTOS_DebugLog("TIMER_ISR_#1::LEAVE");
	RTOS_DebugOutDump();	
}

/*
** User' Timer Handler #2
*/
static volatile uint8_t TimerCounter = 0;
RTOS_ISR_FUNC(USER_TimerHandler_2)
{
	RTOS_DebugLog("TIMER_ISR_#2::ENTER");
	RTOS_DebugOutDump();
	if ( TimerCounter == 0 )
	{
		RTOS_DebugLog("TIMER_ISR_#2::Resume Task#1");
		RTOS_TaskResumeISR(&tsk1PID);	
	}
	if ( TimerCounter == 1 )
	{
		RTOS_DebugLog("TIMER_ISR_#2::Resume Task#3");
		RTOS_TaskResumeISR(&tsk3PID);	
	}
	TimerCounter = (++TimerCounter % 2);
	RTOS_DebugLog("TIMER_ISR_#2::LEAVE");
	RTOS_DebugOutDump();
}

/******************************************************************************
	UNIT TEST TASK FUNCTIONs
******************************************************************************/
/*
** RTOS Task #1
*/
RTOS_TASK_FUNC(tsk1)
{
	while(1)
	{
		RTOS_DebugLog("Task#1:: SUSPEND");
		RTOS_DebugOutDump();	
		RTOS_TaskSuspend(&tsk1PID);
		RTOS_DebugLog("Task#1:: RESUME");
		RTOS_DebugOutDump();
	}
}

/*
** RTOS Task #2 
*/
RTOS_TASK_FUNC(tsk2)
{
	while(1)
	{
		RTOS_DebugLog("Task#2:: SUSPEND");
		RTOS_DebugOutDump();
		RTOS_TaskSuspend(&tsk2PID);		
		RTOS_DebugLog("Task#2:: RESUME");
		RTOS_DebugOutDump();
	}
}

/*
** RTOS Task #3 
*/
RTOS_TASK_FUNC(tsk3)
{
	while(1)
	{
		RTOS_DebugLog("Task#3:: SUSPEND");
		RTOS_DebugOutDump();
		RTOS_TaskSuspend(&tsk3PID);		
		RTOS_DebugLog("Task#3:: RESUME");
		RTOS_DebugOutDump();
	}
}

